<template>
  <div class="home">
    <div class="sideBar">
      <SideBar :graph="graph" v-if="graph" ref="sideBar"></SideBar>
    </div>
    <div id="container">
      <div ref="content" id="content"></div>
    </div>
    <div class="manipulate">
      <Manipulate :graph="graph" v-if="graph" ref="manipulate"></Manipulate>
    </div>
    <saveModalVue @saveOk="saveOK" ref="saveModalVue"></saveModalVue>
  </div>
</template>

<script>
import SideBar from "./components/SideBar";
import Manipulate from "./components/Manipulate";
import saveModalVue from "./modal/saveModal";
import _ from "lodash";
import { initGraph } from "./X6";
// 插件
import { Snapline } from "@antv/x6-plugin-snapline"; // 对齐线
import { Transform } from "@antv/x6-plugin-transform"; // 节点尺寸修改
import { Selection } from "@antv/x6-plugin-selection"; // 框选
import { History } from "@antv/x6-plugin-history"; // 撤销重做
import { Export } from "@antv/x6-plugin-export"; // 导出
import { Clipboard } from "@antv/x6-plugin-clipboard"; // 复制粘贴
import { Keyboard } from "@antv/x6-plugin-keyboard"; // 键盘事件
// mixin
import eventMixin from "./mixin/eventMixin";
export default {
  name: "Home",
  mixins: [eventMixin],
  components: {
    SideBar,
    Manipulate,
    saveModalVue,
  },
  data() {
    return {
      graph: null,
      pickCells: [],
      noUNDO: ["ports", "size", "data"], // 不计入历史记录操作类型
    };
  },
  watch: {
    pickCells: {
      handler(val) {
        if (!val.length) {
          this.resetPanel();
        }
      },
      immediate: true,
    },
  },
  mounted() {
    this.graph = initGraph(this.$refs.content);
    if (this.graph) {
      this.loaclgraphData();
      this.setGraphUse();
      this.graphEventInit();
    }
    // 判断保存状态
    window.onbeforeunload = function (event) {
      return "您可能有数据没有保存";
    };
  },
  methods: {
    showPorts(ports, show) {
      for (let i = 0, len = ports.length; i < len; i += 1) {
        ports[i].style.visibility = show ? "visible" : "hidden";
      }
    },
    selectCell: _.debounce(function (view, type) {
      // 防抖--框选情况
      // 选中节点
      this.handleCellSelect(view, type);
    }, 30),
    setGraphUse() {
      // 插件注册
      this.graph.use(
        new Snapline({
          enabled: true,
        })
      );
      this.graph.use(
        new Transform({
          resizing: {
            enabled: true,
            minWidth: 20,
            maxWidth: 200,
            minHeight: 20,
            maxHeight: 200,
            orthogonal: true,
            restrict: false,
            preserveAspectRatio: false, // 是否保持宽高比
          },
          rotating: {
            enabled: true,
            grid: 15,
          },
        })
      );
      this.graph.use(
        new Selection({
          multiple: true,
          rubberband: true,
          modifiers: ["ctrl"],
          movable: true,
          showNodeSelectionBox: true,
          pointerEvents: "none",
          // showEdgeSelectionBox: true,
          rubberEdge: true,
          following: false, // 多节点框选移动卡顿
        })
      );
      this.graph.use(
        new History({
          enabled: true,
          beforeAddCommand: (event, args) => {
            // 对一些操作的过滤，不计入历史记录
            let { key, options } = args;
            let isRatio = false;
            if (
              Object.prototype.toString.call(options.propertyValue) ===
              "[object Object]"
            ) {
              isRatio = options.propertyValue.name === "ratio";
            }
            if (
              this.noUNDO.includes(key) ||
              isRatio ||
              options.propertyPath === "attrs/label/text"
            ) {
              return false;
            }
            return true;
          },
        })
      );
      this.graph.use(new Export());
      this.graph.use(
        new Keyboard({
          enabled: true,
        })
      );
      this.graph.use(
        new Clipboard({
          // useLocalStorage: true,
          enabled: true,
        })
      );
      this.graph.bindKey("ctrl+c", () => {
        this.handleClipboard("c");
      });
      this.graph.bindKey("ctrl+v", () => {
        this.handleClipboard("v");
      });
      this.graph.bindKey("del", () => {
        this.handleClipboard("del");
      });
    },
    handleCellSelect(view, type) {
      this.pickCells = this.graph.getSelectedCells();
      if (this.pickCells.length > 1) {
        // 多选
        this.$refs.manipulate.init(null);
        this.$emit("handleHeader", this.pickCells, view, type);
        return;
      } else if (this.pickCells.length === 1) {
        // 单选
        this.pickCells[0].shape === "TextNode" ? (type = "textnode") : "";
        this.$refs.manipulate.init(this.pickCells[0], view, type);
        this.$emit("handleHeader", this.pickCells, view, type);
      }
      if (type === "node") {
      } else if (type === "edge") {
      }
    },
    // handleClipboard
    handleClipboard(type) {
      if (type === "c") {
        const cells = this.graph.getSelectedCells();
        if (cells.length) {
          this.$message.success("复制成功");
          // 清除所有选中
          this.graph.cleanSelection();
          this.graph.copy(cells, { deep: true });
        }
      } else if (type === "v") {
        if (!this.graph.isClipboardEmpty()) {
          this.graph.paste({
            offset: 72,
            nodeProps: ["getNodeData"],
          });
          this.$message.success("粘贴成功");
        }
      } else if (type === "del") {
        this.graph.removeCells(this.pickCells);
        this.pickCell = [];
        this.resetPanel();
      }
    },
    // manipulate
    manipulate(type, data) {
      if (type === "delete") {
        this.graph.removeCells(this.pickCells);
        this.pickCell = [];
      } else if (type === "history") {
        if (data === "undo") {
          this.graph.undo();
        } else if (data === "redo") {
          this.graph.redo();
        }
      } else if (type === "export") {
        // test
        this.graph.exportPNG("img", {
          // 导出图片的一些配置
          backgroundColor: "#fff",
          padding: 100, // 图片的padding
          quality: 1,
        });
      } else if (type === "setzIndex") {
        if (data === "toFront") {
          this.pickCells[0].toFront({
            deep: true,
          });
        } else {
          this.pickCells[0].toBack({
            deep: true,
          });
        }
      } else if (type === "zoomIn") {
        this.graph.zoom(0.1);
      } else if (type === "zoomOut") {
        this.graph.zoom(-0.1);
      } else if (type === "toCenter") {
        this.graph.centerContent();
      } else if (type === "save") {
        // 这里调接口存储，想的是存缩略图和数据以及名字啥的信息
        if (window.localStorage.getItem("X6_graphData")) {
          window.localStorage.removeItem("X6_graphData");
        }
        window.localStorage.setItem(
          "X6_graphData",
          JSON.stringify(this.graph.toJSON())
        ); //先本地存一份
        // this.$refs.saveModalVue.open();
      } else if (type === "colorPick") {
        if (!this.pickCells.length) return;
        let cell = this.pickCells[0];
        if (cell.isEdge()) {
          cell.attr("line/stroke", data);
          return;
        } else if (cell.isNode()) {
          cell.setData({
            currentStyle: {
              fill: data,
            },
          });
        }
        return;
      }
      // 重置控件状态
      this.resetPanel();
    },
    saveOK() {
      // 更改保存状态
      this.$emit("setStatus", "needSave", false); // 保存后重置状态
    },
    graphChanged() {
      // 更新历史记录按钮状态
      this.$emit("setStatus", "needSave", true);
    },
    loaclgraphData() {
      // 本地数据
      // if (window.localStorage.getItem("X6_graphData")) {
      //   this.$confirm({
      //     title: "本地存在数据是否加载至画布?",
      //     onOk: () => {
      //       let data = JSON.parse(window.localStorage.getItem("X6_graphData"));
      //       this.graph.fromJSON(data);
      //       this.$emit("setStatus", "needSave", true);
      //     },
      //     onCancel: () => {
      //       return;
      //     },
      //   });
      // }
    },
    resetPanel() {
      this.$nextTick(() => {
        if (this.$refs.manipulate) {
          this.$refs.manipulate.init(null);
        }
        this.$emit("handleHeader", null);
      });
    },
  },
};
</script>
<style scoped lang="less">
.home {
  width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  height: calc(100% - 35px);
  display: flex;

  // flex-direction: column;
  .manipulate {
    width: 230px;
    height: 100%;
  }

  .sideBar {
    width: 200px;
  }

  #container {
    width: calc(100% - 430px);

    #content {
      width: 100%;
      height: 100%;
    }
  }
}

:deep(.x6-widget-selection-box) {
  border: 1.5px dashed #627fff;
}

:deep(.x6-widget-selection-inner) {
  border: 1.5px solid #9023dd;
}

:deep(.x6-widget-transform-rotate:hover) {
  cursor: url("") 8 8,
    crosshair;
}
</style>
